import 'dart:core';

import 'package:flutter/material.dart';

import '../common/flatPanel.dart';
import '../models/topicItem.dart';
import '../parts/topicItemDialog.dart';
import '../utils/dataSource.dart';
import '../utils/screw.dart';

mixin TopicItemControllerWithDrawer {
  final mDrawHeader = 'DrawHeader';
  final mDb = DataSource();

  String mTable;
  int placeHolder = -1;
  var mViewState = ViewState.Initial;
  var mTopic = '';
  var mTopics = <String>[];
  var mItems = <TopicItem>[];
  TopicItem mItem;

  void onUpdateView();

  void onUpdateTopics();

  void onAddItem();

  void onEditItem();

  void onDeleteItem();

  void onTapItem();

  Future<void> connectDbAction(
      BuildContext context, String configName, Function function) async {
    bool result = await mDb.connectDB(configName);
    if (result) {
      function();
    } else {
      Screw.showToast(context, '无法连接到数据库!');
    }
  }

  Future<void> openUrlAction() async {
    if (mItem.detail.isEmpty) return;
    if (mItem.detail.startsWith('http')) await Screw.openUrl(mItem.detail);
  }

  Future<void> addItemAction(BuildContext context) async {
    var inputItem = TopicItem();
    if (mTopic.isNotEmpty) inputItem.topic = mTopic;

    var item = await showTopicItemDialog(context, item: inputItem);
    if (mDb.isConnect) {
      var result = await mDb.query(
          'insert into $mTable (topic,label,detail,addition) values (?,?,?,?)',
          [item.topic, item.label, item.detail, item.addition]);
      if (result.affectedRows == 1) onUpdateView();
    }
  }

  Future<void> editItemAction(BuildContext context) async {
    if (mItem == null || mItem.id == 0) return;

    var item = await showTopicItemDialog(context, item: mItem);

    if (mItem.isEqual(item)) return;

    if (mDb.isConnect) {
      var result = await mDb.query(
          'update $mTable set topic=?,label=?,detail=?,addition=? where id=?',
          [item.topic, item.label, item.detail, item.addition, item.id]);
      if (result.affectedRows == 1) onUpdateView();
    }
  }

  Future<void> deleteItemAction() async {
    if (mItem.id == 0) return;

    if (mDb.isConnect) {
      var result =
          await mDb.query('delete from $mTable where id=?', [mItem.id]);
      if (result.affectedRows == 1) onUpdateView();
    }
  }

  Future<void> updateTopics() async {
    if (mTopics.isNotEmpty) mTopics.clear();

    if (mDb.isConnect) {
      var items = <String>[];
      var results = await mDb.query('select topic from $mTable group by topic');
      results.forEach((element) {
        items.add(element[0]);
      });
      mTopics = items;
    }
  }

  Future<void> updateTopicsWithDrawerAction() async {
    if (mTopics.isNotEmpty) mTopics.clear();
    mTopics.add(mDrawHeader);

    if (mDb.isConnect) {
      var items = <String>[];
      var results = await mDb.query('select topic from $mTable group by topic');
      results.forEach((element) {
        items.add(element[0]);
      });
      mTopics = items;
    }
  }

  Future<void> updateViewAction() async {
    if (mTopic.isEmpty) return;

    if (mDb.isConnect) {
      var items = <TopicItem>[];
      var results = await mDb.query(
          'select id,label,detail,addition from $mTable where topic=?',
          [mTopic]);
      results.forEach((element) {
        var item = TopicItem(
            id: element[0],
            topic: mTopic,
            label: element[1] ?? '',
            detail: element[2] ?? '',
            addition: element[3] ?? '');
        items.add(item);
      });
      mItems = items;
    }
  }

  void disposeAction() {
    mTopics.clear();
    mItems.clear();
    mDb.close();
  }

  Widget genTopicViewAction() {
    return ListView.builder(
        itemCount: mTopics.length,
        itemBuilder: (c, index) {
          return ListTile(
              leading: Icon(Icons.arrow_forward_ios),
              title: Text(mTopics[index]),
              onTap: () {
                mTopic = mTopics[index];
                onUpdateView();
              });
        });
  }

  Widget genTopicViewWithDrawerAction(BuildContext context) {
    return ListView.builder(
        // padding: EdgeInsets.zero,
        itemCount: mTopics.length,
        itemBuilder: (c, index) {
          if (index == 0) return genDrawerHeaderAction();
          return ListTile(
              leading: Icon(Icons.title),
              title: Text(mTopics[index], style: TextStyle(fontSize: 18)),
              onTap: () {
                mTopic = mTopics[index];
                onUpdateView();
                Navigator.of(context).pop();
              });
        });
  }

  Widget genGridViewAction() {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        //子组件宽高长度比例
        childAspectRatio: 8.0,
      ),
      itemCount: mItems.length,
      itemBuilder: (c, index) {
        return ListTile(
          title: Text(mItems[index].label, style: TextStyle(fontSize: 18)),
          subtitle: Text(mItems[index].detail),
          onTap: () {
            mItem = mItems[index];
            onTapItem();
          },
        );
      },
    );
  }

  Widget genListViewAction() {
    return ListView.separated(
      itemCount: mItems.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(mItems[index].label, style: TextStyle(fontSize: 18)),
          subtitle: Text(mItems[index].detail),
          onTap: () {
            mItem = mItems[index];
            onTapItem();
          },
        );
      },
      separatorBuilder: (context, i) => Divider(),
    );
  }

  Widget genDrawerHeaderAction() {
    return DrawerHeader(
      decoration: BoxDecoration(color: Colors.lightBlueAccent),
      child: Center(
        child: SizedBox(
          width: 60,
          height: 60,
          child: CircleAvatar(child: Text('Topic')),
        ),
      ),
    );
  }

  Future<void> _showDeleteConfirmDialog(BuildContext context) async {
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text('操作确认'),
            content: Text('确定要删除吗？不可恢复！'),
            actions: <Widget>[
              FlatButton(
                child: Text('取消'),
                onPressed: () => Navigator.of(context).pop(),
              ),
              FlatButton(
                child: Text('确定'),
                onPressed: () {
                  onDeleteItem();
                  Navigator.of(context).pop();
                },
              ),
            ],
          );
        });
  }

  showContextMenu(BuildContext context, LongPressEndDetails details) {
    var dx = details.globalPosition.dx;
    var dy = details.globalPosition.dy;
    var width = MediaQuery.of(context).size.width;
    var height = MediaQuery.of(context).size.height;
    var mWidth = 60, mHeight = 50;

    showMenu(
      context: context,
      position: RelativeRect.fromLTRB(dx - mWidth, dy - mWidth,
          width - dy + mHeight, height - dy + mHeight),
      items: <PopupMenuEntry<String>>[
        PopupMenuItem<String>(
          value: 'Edit',
          child: ListTile(
            leading: Icon(Icons.edit),
            title: Text('编辑...'),
            onTap: () => onEditItem(),
          ),
        ),
        PopupMenuDivider(),
        PopupMenuItem<String>(
          value: 'Delete',
          child: ListTile(
            leading: Icon(Icons.delete),
            title: Text('删除'),
            onTap: () => _showDeleteConfirmDialog(context),
          ),
        ),
      ],
    );
  }
}
